/*
 * FdLimit.cpp
 *
 *  Created on: 2022年7月25日
 *      Author: terry
 */

#include "FdLimit.h"
#include <string.h>
#include "TStringUtil.h"

#ifdef WIN32
    #include <Psapi.h>
#else
    #include <sys/types.h>
    #include <sys/wait.h>
	#include <sys/resource.h>
#endif //

#if defined(_MSC_VER)
#pragma comment(lib, "Psapi.lib")
#endif


#include "PipeReader.h"


FdLimit::FdLimit()
{
}

FdLimit::~FdLimit()
{
}

#ifdef WIN32
bool FdLimit::setMax(size_t maxsize)
{
	return false;
}

size_t FdLimit::getMax()
{
	return 10000;
}

size_t FdLimit::getCount()
{
    DWORD dwHandleCount;
    GetProcessHandleCount(GetCurrentProcess(), &dwHandleCount);
    return dwHandleCount;
}

#else
bool FdLimit::setMax(size_t maxsize)
{
	pid_t pid = getCurPid();
	rlimit limit = rlimit();
	limit.rlim_cur = maxsize;
	limit.rlim_max = maxsize;
	int ret = prlimit(pid, RLIMIT_NOFILE, &limit, nullptr);
	return ret == 0;
}

size_t FdLimit::getMax()
{
	size_t count = 0;
	pid_t pid = getCurPid();
	rlimit limit = rlimit();
	int ret = prlimit(pid, RLIMIT_NOFILE, nullptr, &limit);
	if (ret == 0)
	{
		count = limit.rlim_max;
	}
	return count;
}

size_t FdLimit::getCount()
{
	pid_t pid = getCurPid();
	std::string cmdline = comn::StringUtil::format("ls /proc/%d/fd | wc -w", pid);
	//std::string cmdline = comn::StringUtil::format("lsof -p %d | wc -l", pid);
	std::string text;
	PipeReader::read(cmdline, text);
	size_t count = 0;
	comn::StringCast::toValue(text, count);
	return count > 0 ? count - 1 : count;
}

#endif //

pid_t FdLimit::getCurPid()
{
#ifdef WIN32
    return GetCurrentProcessId();
#else
    return getpid();
#endif //
}
